package com.bckj.fastboot.paid.biz.infrastructure.sdk.wechatpay.jsapi;

import cn.hutool.core.util.NumberUtil;
import com.bckj.fastboot.paid.api.constant.PayWayConstants;
import com.bckj.fastboot.paid.api.entity.PayConfig;
import com.bckj.fastboot.paid.api.entity.PayMerchantConfig;
import com.bckj.fastboot.paid.biz.domain.pay.provider.PayGatewayProvider;
import com.bckj.fastboot.paid.biz.domain.pay.gateway.PayGateway;
import com.bckj.fastboot.paid.api.exceptions.PayException;
import com.bckj.fastboot.paid.biz.infrastructure.sdk.PayServiceManager;
import com.bckj.fastboot.paid.api.model.PayRequest;
import com.bckj.fastboot.paid.api.model.PayResponse;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;

@Component
@RequiredArgsConstructor
public class WechatJsapiPayGateway implements PayGateway {

    private final PayServiceManager payServiceManager;

    @PostConstruct
    public void init() {
        PayGatewayProvider.register(getPayWay(), this);
    }

    @Override
    public String getPayWay() {
        return PayWayConstants.WECHAT_PAY_JSAPI;
    }

    public PayResponse pay(PayRequest request) throws PayException {
        WechatpayJsapiPayServiceWrapper payServiceWrapper = (WechatpayJsapiPayServiceWrapper) payServiceManager.getPayService(request.getAppId(), request.getPayWay());
        JsapiService payService = (JsapiService) payServiceWrapper.getService();
        PrepayRequest wechatRequest = toWechatRequest(request);
        PayConfig payConfig = payServiceWrapper.getPayConfigWrapper().getPayConfig();
        PayMerchantConfig payMerchantConfig = payConfig.getPayMerchantConfig();
        wechatRequest.setMchid(payMerchantConfig.getOutMerchantId());
        try {
            PrepayResponse wechatResponse = payService.prepay(wechatRequest);
            return toPayResponse(wechatResponse);
        } catch (Exception e) {
            throw new PayException("WechatJsapi Error:" + e.getMessage());
        }
    }

    private PrepayRequest toWechatRequest(PayRequest request) {
        PrepayRequest wechatRequest = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(NumberUtil.mul(request.getAmount(), new BigDecimal("100")).intValue());
        wechatRequest.setAmount(amount);
        wechatRequest.setAppid(request.getAppId());
        wechatRequest.setDescription(request.getDescribe());
        wechatRequest.setNotifyUrl(request.getNotifyUrl());
        wechatRequest.setOutTradeNo(request.getRequestNo());
        return wechatRequest;
    }

    private PayResponse toPayResponse(PrepayResponse wechatResponse) {
        PayResponse response = new PayResponse();
        response.setPrepayId(wechatResponse.getPrepayId());
        return response;
    }
}
